<!--
 * @Author: rxn 1003312535@qq.com
 * @Date: 2024-07-05 15:25:53
 * @LastEditors: rxn 1003312535@qq.com
 * @LastEditTime: 2024-07-29 16:56:23
 * @FilePath: \vue3-progect\src\views\example\three\geometry\index.vue
 * @Description: 管道漫游
-->
<!--相机基础-->
<template>
	<div id="three_container"></div>
</template>

<script setup>
import * as THREE from "three";
import { onMounted, ref } from "vue";
//-
import { AxesHelper } from "../case/helper/AxesHelper";
//-
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
let scene, renderer, camera, controls, pointsArr;
onMounted(() => {
	let container = document.getElementById("three_container");
	scene = new THREE.Scene();
	// 正投影相机
	const width = container.offsetWidth; //canvas画布宽度
	const height = container.offsetHeight; //canvas画布高度
	const k = width / height; //canvas画布宽高比
	const s = 200; //控制left, right, top, bottom范围大小
	camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 11000);
	camera.position.set(200, 300, 200); //设置相机位置
	// camera.lookAt(scene.position); //设置相机方向(指向的场景对象)
	// camera = createCamera(THREE, container);

	//--
	renderer = new THREE.WebGLRenderer({
		antialias: true
	});
	renderer.setSize(container.offsetWidth, container.offsetHeight);
	container.appendChild(renderer.domElement);
	renderer.render(scene, camera);

	//--
	controls = new OrbitControls(camera, renderer.domElement);
	controls.update();
	//--
	const axesHelper = new THREE.AxesHelper(800);
	scene.add(axesHelper);
	animate(renderer, scene, camera);
	//--
	const ambient = new THREE.AmbientLight("#ffffff");
	scene.add(ambient);
	demo();
});
let i = 0;
const animate = (renderer, scene, camera) => {
	if (pointsArr && i < pointsArr.length - 1) {
		// 相机位置设置在当前点位置
		camera.position.copy(pointsArr[i]);
		// 曲线上当前点pointsArr[i]和下一个点pointsArr[i+1]近似模拟当前点曲线切线
		// 设置相机观察点为当前点的下一个点，相机视线和当前点曲线切线重合
		camera.lookAt(pointsArr[i + 1]);
		// camera.lookAt(200, 0, 1200);
		controls.target.copy(pointsArr[i + 1]);
		controls.update();
		i += 1; //调节速度
	} else {
		i = 0;
	}
	requestAnimationFrame(animate.bind(this, renderer, scene, camera));
	renderer.render(scene, camera);
};

const demo = () => {
	// 三维样条曲线
	const path = new THREE.CatmullRomCurve3([
		new THREE.Vector3(-50, 20, 90),
		new THREE.Vector3(-10, 40, 40),
		new THREE.Vector3(0, 0, 0),
		new THREE.Vector3(60, -60, 0),
		new THREE.Vector3(90, -40, 60),
		new THREE.Vector3(120, 30, 30)
	]);
	let points = path.getPoints(100);
	const geometry = new THREE.BufferGeometry();
	geometry.setFromPoints(points);
	const lineMaterial = new THREE.LineBasicMaterial({ color: 0xaaaaaa });
	const lineMesh = new THREE.Line(geometry, lineMaterial);
	scene.add(lineMesh);

	const tubeGeometry = new THREE.TubeGeometry(path, 200, 5, 30);
	const baseMaterial = new THREE.MeshLambertMaterial({ color: 0xff00ff });
	const tubeMesh = new THREE.Mesh(tubeGeometry, baseMaterial);
	// scene.add(tubeMesh);

	//-
	const url = new URL("@/assets/image/RenNing.png", import.meta.url).href;
	const texture = new THREE.TextureLoader().load(url);
	const tubeMaterial = new THREE.MeshLambertMaterial({
		map: texture,
		side: THREE.DoubleSide //双面显示看到管道内壁
	});
	const textureMesh = new THREE.Mesh(tubeGeometry, tubeMaterial);
	scene.add(textureMesh);
	//-
	pointsArr = path.getSpacedPoints(500);
	// const i = 0;
	// setInterval(() => {
	// 	console.log(1);
	// 	// 相机位置：曲线上当前点pointsArr[i]
	// 	camera.position.copy(pointsArr[i]);
	// 	controls.target.copy(pointsArr[i + 1]);
	// 	controls.update();
	// 	// 相机观察目标：当前点的下一个点pointsArr[i + 1]
	// 	camera.lookAt(pointsArr[i + 1]);
	// }, 30);
};
</script>

<style lang="less" scoped>
#three_container {
	height: 100%;
}
.downLoadBtn {
	position: absolute;
	right: 0;
	top: 10px;
	z-index: 99;
}
</style>
